package org.example.wu_and_dian.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.example.wu_and_dian.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtException;
import org.example.wu_and_dian.utils.TokenUtils;
import org.example.wu_and_dian.config.UserContext;

@Aspect
@Component
public class TokenAspect {
    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 定义一个切点，匹配所有使用 @TokenRequired 注解的方法
     */
    @Pointcut("@annotation(org.example.wu_and_dian.annotation.TokenRequired)")
    public void tokenRequiredPointcut() {
    }

    /**
     * 在使用 @TokenRequired 注解的方法执行前执行该方法进行 Token 校验
     * 
     * @param joinPoint 切入点
     */
    @Before("tokenRequiredPointcut()")
    public void checkToken(JoinPoint joinPoint) {
        // 获取当前请求
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes())
                .getRequest();

        // 获取请求头中的 token
        String token = request.getHeader("Authorization");
        if (token != null && token.startsWith("Bearer ")) {
            token = token.substring(7); // 去掉 Bearer 前缀
        }
        if (token == null) {
            throw new RuntimeException("Token is required");
        }

        try {
            // 解析 token
            Claims claims = TokenUtils.parseToken(token);
            String email = claims.get("email", String.class);
            String Password = claims.get("password", String.class);
            // 从服务器存储中获取该用户的token
            String storedToken = (String) redisTemplate.opsForValue().get("user_token:" + email);

            // 比对token
            if (storedToken == null || !storedToken.equals(token)) {
                throw new RuntimeException("token is invalid");
            }
            UserContext.set(email,Password);
        } catch (JwtException e) {
            throw new RuntimeException("Invalid token", e);
        }
    }
}